
package ComponentDnDExample.test;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;

import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.MouseEvents;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.AbsoluteLayout.ComponentPosition;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.DragAndDropWrapper;
import com.vaadin.ui.DragAndDropWrapper.DragStartMode;
import com.vaadin.ui.DragAndDropWrapper.WrapperTargetDetails;
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class ComponentDnDExample extends CustomComponent {
    private static final long serialVersionUID = -8301626324227210030L;

    String context;
    
    public void init(String context) {
        this.context = context;
        System.out.println("kontekst");
    }
    
    @Override
    public void attach() {
            absolute();
    }

    void component() {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);

        // BEGIN-EXAMPLE: advanced.dragndrop.component
        // A place for our draggable component
        VerticalLayout sourceArea = new VerticalLayout();
        layout.addComponent(sourceArea);
        
        // The draggable component
        Panel panelToDrag = new Panel("Panel to Drag");
        panelToDrag.setWidth("200px");
        panelToDrag.addComponent(new Label(
                "<h1>Draggable Panel</h1>"+
                "<p>You can drag this panel to any of the "+
                "placeholder locations on right.</p>",
                Label.CONTENT_XHTML));
        ((VerticalLayout) panelToDrag.getContent()).setMargin(false);
        sourceArea.addComponent(panelToDrag);
        
        
        VerticalLayout targetArea = new VerticalLayout();
        layout.addComponent(targetArea);
        
        //DragAndDropWrapper targetWrapper =
        //    new DragAndDropWrapper(targetArea);
        
        // END-EXAMPLE: advanced.dragndrop.component
        
        setCompositionRoot(layout);
    }
    DragAndDropWrapper addNewComponent(DragAndDropWrapper wrapper){
    	//odpowiada za chwytanie elementu i widoczny obraz elementu podczas zmiany jego polozenia
    	wrapper.setDragStartMode(DragStartMode.WRAPPER);
    	//wrapper.setDragStartMode(DragStartMode.NONE);
    	// Set the wrapper to wrap tightly around the component
    	wrapper.setSizeUndefined();
    	return wrapper;
    }
    void absolute() {
        // BEGIN-EXAMPLE: advanced.dragndrop.component.absolute
        // A layout that allows moving its contained components
        // by dragging and dropping them
        final AbsoluteLayout absLayout = new AbsoluteLayout();
        absLayout.setWidth("600px");
        absLayout.setHeight("300px");
        
        // Have a component to drag
        final Button button = new Button("Moj przycisk");
        button.addListener(new Button.ClickListener() {
            private static final long serialVersionUID = -3420821329748965552L;
            public void buttonClick(ClickEvent event) {
            	getWindow().showNotification("Witaj");
            }
        });
        // Put the component in a D&D wrapper and allow dragging it
        //tylko final
        DragAndDropWrapper buttWrap = new DragAndDropWrapper(button);
        buttWrap=addNewComponent(buttWrap);
        //buttWrap.setDragStartMode(DragStartMode.WRAPPER);
    	// Set the wrapper to wrap tightly around the component
        //buttWrap.setSizeUndefined();
        // Add the wrapper, not the component, to the layout
        absLayout.addComponent(buttWrap, "left: 50px; top: 50px;");
        
        // Have another component to drag
        /*final TextField text = new TextField("This Can Not Be Seen");
        final DragAndDropWrapper textWrap = new DragAndDropWrapper(text);
        textWrap.setCaption("I Has a Caption!");
        textWrap.setDragStartMode(DragStartMode.WRAPPER);
        textWrap.setSizeUndefined();
        absLayout.addComponent(textWrap, "left: 250px; top: 80px;");*/
        TextField text = new TextField("");
        DragAndDropWrapper textWrap = new DragAndDropWrapper(text);
        textWrap=addNewComponent(textWrap);
        absLayout.addComponent(textWrap, "left: 20px; top: 80px;");


        // Another component to drag
         Panel panel = new Panel("Moj Panel");
        panel.setWidth("150px");
        panel.addComponent(new Label(
                "<p>To jest panel z etykietą.</p>"+
                "<p>Mozesz go przenosic myszką.</p>",
                Label.CONTENT_XHTML));
        ((VerticalLayout) panel.getContent()).setMargin(false);
        DragAndDropWrapper panelWrap = new DragAndDropWrapper(panel);
        panelWrap=addNewComponent(panelWrap);
        absLayout.addComponent(panelWrap, "left: 100px; top: 100px;");
        //absLayout.addComponent(panel, "left: 100px; top: 100px;");

        // Wrap the layout to allow handling drops
        DragAndDropWrapper layoutWrapper =
                new DragAndDropWrapper(absLayout);
        
        addStyleName("no-vertical-drag-hints");//bez pokazywania linii vertical - granicy przenoszenia obiektu
        addStyleName("no-horizontal-drag-hints");//bez pokazywania linii horizontal - granicy przenoszenia obiektu
        addStyleName("no-box-drag-hints");//bez pokazywania zarysu elementu 
        
        // Handles drops both on an AbsoluteLayout and
        // on components contained within it
        class MoveHandler implements DropHandler {
            private static final long serialVersionUID = -5709370299130660699L;

            public AcceptCriterion getAcceptCriterion() {
                return AcceptAll.get();
            }

            public void drop(DragAndDropEvent event) {
            	/*
            	 * pobieranie wrapper-a danego obiektu
            	 */
                WrapperTransferable t =
                    (WrapperTransferable) event.getTransferable();
            	System.out.println("WrapperTransferable>"+t.toString());
                WrapperTargetDetails details =
                    (WrapperTargetDetails) event.getTargetDetails();
                System.out.println("WrapperTargetDetails>"+details.toString());
                
                int[] position1={
                		details.getMouseEvent().getClientX()
                        - t.getMouseDownEvent().getClientX(),
                        details.getMouseEvent().getClientY()
                        - t.getMouseDownEvent().getClientY()
                };
                // Move the component in the absolute layout
                ///////// (C) ///////////
                RememberActualPosition(t,position1);
                ///////// (C) ///////////
            }
            /*
             * ustawienie nowego polozenia elementu po operacji upuszczenia
             */
            void RememberActualPosition(WrapperTransferable t,int ... position){
            	ComponentPosition pos =
            			absLayout.getPosition(t.getSourceComponent());
            	pos.setLeftValue(pos.getLeftValue() + position[0]);
            	pos.setTopValue(pos.getTopValue() + position[1]);
            }
        }        

        // Handle moving components within the AbsoluteLayout
        /*
         * sluzy do przenoszenia obiektow dodanie Handler-a do warstwy powoduje zatrzymanie elementu
         * na warstwie o ile (C) w tym kodzie jest odkomentowane 
         */
        ///////// (D) ///////////
        layoutWrapper.setDropHandler(new MoveHandler());
        ///////// (D) ///////////
        
        // Handle cases where a component is dropped on another
        // component
        ///////// (E) ///////////
        for (Iterator<Component> i =
                 absLayout.getComponentIterator(); i.hasNext();)
            ((DragAndDropWrapper)i.next()).setDropHandler(new MoveHandler());
        ///////// (E) ///////////
        // Put the drag area in a layout that has some extra controls
        VerticalLayout layout = new VerticalLayout();
        layout.addComponent(layoutWrapper);
        layoutWrapper.setSizeUndefined();
        layoutWrapper.addStyleName("layoutwrapper");
        setSizeFull();
        addStyleName("componentdndexample");
        setCompositionRoot(layout);
    }

}
